共计 2549 个字符,预计需要花费 7 分钟才能阅读完成。
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义。在简化的计算机网络 OSI 模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内,另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP 层是位于 IP 层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是 IP 层不提供这样的流机制,而是提供不可靠的包交换。
正文
在上一篇 《Java-UDP 协议数据传输简单小案例》 文章使用了 UDP 协议进行数据传输展示,UDP 协议是一种不可靠的传输协议,因为再数据发送之后,我们是无法得知其是否安全完整到达的。
TCP 协议文章开头已经介绍了,是一种可靠的基于字节流的传输层通信协议,可靠之处在哪里呢?具体请详见TCP(传输控制协议),另外 HTTP 协议就是一个很好的例子。
发送端
import java.io.*;
import java.net.Socket;
public class ClientDemo2 {public static void main(String[] args) {
String path = "F:"+ File.separator+"test"+ File.separator+"1.jpg";
File file = new File(path);
try {Socket socket = new Socket("127.0.0.1",5555);
OutputStream out = socket.getOutputStream();
InputStream in = new FileInputStream(file);
int len = 0;
byte[] b = new byte[200];
while ((len = in.read(b))!=-1){out.write(b,0,len);
}
in.close();
out.close();
socket.close();} catch (IOException e) {e.printStackTrace();
}
}
}
服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ServerDemo2 {public static void main(String[] args) {
try {ServerSocket serverSocket = new ServerSocket(5555);
while(true){Socket socket = serverSocket.accept();
new Thread(new Save(socket)).start();}
} catch (IOException e) {e.printStackTrace();
}
}
}
class Save implements Runnable{
private Socket s = null;
public Save(Socket s) {this.s = s;}
@Override
public void run() {
String path = "F:"+ File.separator+"test"+ File.separator+"serverImg"+ File.separator;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmsssss");
File isPath = new File(path);
if(!isPath.exists() || !isPath.isDirectory()){isPath.mkdir();
}
try {InputStream in = s.getInputStream();
byte[] b = new byte[200];
String fileName = Tools.MD5(simpleDateFormat.format(new Date()));
String filePath = path+fileName+".jpg";
OutputStream out = new FileOutputStream(filePath);
int len = 0;
while((len = in.read(b))!=-1){out.write(b,0,len);
}
out.close();
in.close();} catch (IOException e) {e.printStackTrace();
}
}
}
abstract class Tools{public final static String MD5(String pwd) {char md5String[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };
try {byte[] btInput = pwd.getBytes();
MessageDigest mdInst = MessageDigest.getInstance("MD5");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) { // i = 0
byte byte0 = md[i]; //95
str[k++] = md5String[byte0 >>> 4 & 0xf]; // 5
str[k++] = md5String[byte0 & 0xf]; // F
}
return new String(str);
} catch (Exception e) {return null;}
}
}
在上方的服务器端中,为了避免文件名重复而造成文件被覆盖,采用了获取当前的时间(也可以更换成时间戳),然后再进行 MD5 加密使用 32 位密文进行命名,因为时间精确到了毫秒,一般都不会出现重名的现象。
正文完
使用官方微信小程序体验更多功能